package study.alex.resumedb.gae;

import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.data.Item;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.*;
import com.vaadin.ui.Field;
import study.alex.resumedb.gae.model.Contact;
import study.alex.resumedb.gae.model.Resume;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.text.MessageFormat;import java.util.List;
import java.util.logging.Logger;

/**
 * Created with IntelliJ IDEA.
 * User: alex
 * Date: 27.01.14
 * Time: 15:36
 * SVN $Id$
 */
public class HistoryUpdateStatusWindow extends Window implements Button.ClickListener {

    private final Button saveButton;
    private final Button cancelButton;
    private final Item historyItem;
    private final Resume resume;
    private final FieldGroup editorForm;
    private final Label resumeInfo = new Label("", ContentMode.PREFORMATTED);
    private final FormLayout historyForm = new FormLayout();

    public HistoryUpdateStatusWindow(Item historyItem, Resume resume) {
        assert resume != null : "Resume have to present";
        assert historyItem != null : "Item have to present";

        this.historyItem = historyItem;
        this.resume = resume;

        editorForm = new FieldGroup(historyItem);
        editorForm.setBuffered(true);

        saveButton = new Button(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("save"), this);
        cancelButton = new Button(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("cancel"), this);

        HorizontalLayout buttons = new HorizontalLayout(saveButton, cancelButton);
        buttons.setSizeUndefined();
        buttons.setSpacing(true);
        String emplId = (String)historyItem.getItemProperty("employer").getValue();
        Contact empl = getEmployer(emplId);

        if (empl != null) fillSentResumeContactInfo(empl.getName(), empl.getOrganization(), empl.getPhones(), empl.getEmails());

        final DateField lastField = new DateField(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("last.call"));
        lastField.setConverter(new DateConverter());
        editorForm.bind(lastField, "lastcall");
        final DateField nextField = new DateField(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("next.call"));
        nextField.setConverter(new DateConverter());
        editorForm.bind(nextField, "nextcall");
        final DateField dateOfInterview = new DateField(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("date.of.interview"));
        dateOfInterview.setConverter(new DateConverter());
        editorForm.bind(dateOfInterview, "dateofinterview");

        final Field statusField = editorForm.buildAndBind("", "status", NativeSelect.class);
        final TextArea commentField = editorForm.buildAndBind("", "comment", TextArea.class);
        commentField.setWordwrap(true);
        commentField.setRows(5);
        commentField.setColumns(40);

        final HorizontalLayout dates = new HorizontalLayout();
        dates.setSpacing(true);
        dates.setSizeUndefined();
        dates.setDefaultComponentAlignment(Alignment.TOP_CENTER);
        dates.addComponents(lastField, nextField, dateOfInterview);

        historyForm.setSpacing(true);
        historyForm.setDefaultComponentAlignment(Alignment.TOP_CENTER);
        historyForm.setSizeUndefined();
        historyForm.addComponents(dates, statusField, commentField);

        final VerticalLayout rootPanel = new VerticalLayout();
        rootPanel.setSizeFull();
        rootPanel.setSpacing(true);
        rootPanel.setMargin(true);
        rootPanel.setDefaultComponentAlignment(Alignment.TOP_CENTER);
        rootPanel.addComponents(resumeInfo, new HorizontalLayout(historyForm), buttons);
        rootPanel.setComponentAlignment(buttons, Alignment.BOTTOM_CENTER);

        setWidth("35%");
        setHeight("50%");
        setContent(rootPanel);
        setCaption(buildCaption());
        center();
        setModal(true);
    }

    private Contact getEmployer(String id) {
        EntityManager em = JPAContainerFactory.createEntityManagerForPersistenceUnit(EMF.PERSISTENCE_UNIT);

        try {
            Query q = em.createQuery("SELECT cont FROM study.alex.resumedb.gae.model.Contact cont WHERE cont.id = '" + id + "'", Contact.class);
            List<Contact> list = (List<Contact>)q.getResultList();
            Logger.getLogger(HistoryUpdateStatusWindow.class.getName()).fine("Got Contact info: " + list + " Size is " + list.size());
            if (list != null && list.size() > 0) return list.get(0);
            else return null;
        } finally {
            em.close();
        }
    }



    private void fillSentResumeContactInfo(String name, String pos, String phones, String emails) {
        if (name != null && pos != null && phones != null && emails != null) {
            resumeInfo.setValue(
                    (name.equals("") ? "" : (MessageFormat.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("person.0"), name))) +
                            (pos.equals("") ? "" : (MessageFormat.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("organization.0"), pos))) +
                            (phones.equals("") ? "" : (MessageFormat.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("phones.0"), phones))+" ") +
                            (emails.equals("") ? "" : (MessageFormat.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("e.mails.0"), emails))));
        }
        else resumeInfo.setValue("");
        resumeInfo.setSizeUndefined();
    }

    /**
         * @return the caption of the editor window
         */
    private String buildCaption() {
        return String.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("update.sent.record.status.position.s"), resume.getPosition());
    }

    @Override
    public void buttonClick(Button.ClickEvent event) {
        if (event.getButton() == saveButton) {
            try {
                editorForm.commit();
                fireEvent(new EditorSavedEvent(this, historyItem));
            } catch (FieldGroup.CommitException e) {
                Logger.getLogger(HistoryAddWindow.class.getName()).fine("Error in input date in Update History Form");
                return;
            }
        } else if (event.getButton() == cancelButton) {
            editorForm.discard();
        }
        close();
    }

    public void addListener(EditorSavedListener listener) {
        try {
            Method method = EditorSavedListener.class.getDeclaredMethod(
                    "editorSaved", new Class[] { EditorSavedEvent.class });
            addListener(EditorSavedEvent.class, listener, method);
        } catch (final java.lang.NoSuchMethodException e) {
            // This should never happen
            throw new java.lang.RuntimeException(
                    "Internal error, editor saved method not found");
        }
    }

    public void removeListener(EditorSavedListener listener) {
        removeListener(EditorSavedEvent.class, listener);
    }

    public static class EditorSavedEvent extends Component.Event {

        private Item savedItem;

        public EditorSavedEvent(Component source, Item savedItem) {
            super(source);
            this.savedItem = savedItem;
        }

        public Item getSavedItem() {
            return savedItem;
        }
    }

    public interface EditorSavedListener extends Serializable {
        public void editorSaved(EditorSavedEvent event);
    }
}
